package app.util.image.calc
{
	import app.util.image.*;
	
	import flash.display.*;
	import flash.geom.*;
	
	public class MorphUtility
	{
		public static function autoThreshold(data:BitmapData):BinaryBitmapData
		{
			var threshold:Number = BMPUtility.calcThreshold(data);
			var biData:BinaryBitmapData = BinaryBitmapData.generateFromBmp(data, threshold);
			return biData;
		}		

		public static function autoGray(data:BitmapData):GrayBitmapData
		{
			var gData:GrayBitmapData = GrayBitmapData.generateFromBmp(data);
			return gData;
		}		
		
		public static function getDefaultSE():StructureElement
		{
			return StructureElement.createCrossSE(1);
		}
		
		public static function doDilation(src:BinaryBitmapData, se:StructureElement):BinaryBitmapData
		{
			var w:int = src.getWidth();
			var h:int = src.getHeight();
			var dest:BinaryBitmapData = new BinaryBitmapData(w, h);
			for(var x:int = 0; x < w; x++)
			{
				for(var y:int = 0; y < h; y++)
				{
					if(src.isMarked(x, y))
					{
						var originX:int = int(se.orign.x);
						var originY:int = int(se.orign.y);
						var kernel:Array = se.marked;
						for each(var p:Point in kernel)
						{
							var px:int = int(p.x);
							var py:int = int(p.y);
							dest.setMarked(x + (px - originX), y + (py - originY));
						}
					}	
				}
			}
			return dest;
		} 		
		
		public static function doErosion(src:BinaryBitmapData, se:StructureElement):BinaryBitmapData
		{
			var w:int = src.getWidth();
			var h:int = src.getHeight();
			var dest:BinaryBitmapData = src.clone();
			for(var x:int = 0; x < w; x++)
			{
				for(var y:int = 0; y < h; y++)
				{
					if(src.isMarked(x, y))
					{
						var keep:Boolean = true;
						var originX:int = int(se.orign.x);
						var originY:int = int(se.orign.y);
						var kernel:Array = se.marked;
						
						for each(var p:Point in kernel)
						{
							var px:int = int(p.x);
							var py:int = int(p.y);
							var dx:int = x + (px - originX);
							var dy:int = y + (py - originY);
							if(!src.isMarked(dx, dy))
							{
								keep = false;	
								break;
							}
						}
						
						if(!keep)
						{
							dest.setMarked(x, y, false);
						}
					}	
				}
			}
			return dest;
		} 	
		
		public static function doGrayErosion(src:GrayBitmapData, se:StructureElement):GrayBitmapData
		{
			var w:int = src.getWidth();
			var h:int = src.getHeight();
			var dest:GrayBitmapData = new GrayBitmapData(w, h);
			for(var x:int = 0; x < w; x++)
			{
				for(var y:int = 0; y < h; y++)
				{
					var originX:int = int(se.orign.x);
					var originY:int = int(se.orign.y);
					var kernel:Array = se.marked;
					var minG:int = 256; 
					for each(var p:Point in kernel)
					{
						var px:int = int(p.x);
						var py:int = int(p.y);
						var g:int = src.getGray(x + (px - originX), y + (py - originY));
						if(g < minG) minG = g;
					}	
					
					dest.setGray(x, y, minG);
				}
			}
			return dest;
		} 
		
		public static function doGrayDilation(src:GrayBitmapData, se:StructureElement):GrayBitmapData
		{
			var w:int = src.getWidth();
			var h:int = src.getHeight();
			var dest:GrayBitmapData = new GrayBitmapData(w, h);
			for(var x:int = 0; x < w; x++)
			{
				for(var y:int = 0; y < h; y++)
				{
					var originX:int = int(se.orign.x);
					var originY:int = int(se.orign.y);
					var kernel:Array = se.marked;
					var maxG:int = -1; 
					for each(var p:Point in kernel)
					{
						var px:int = int(p.x);
						var py:int = int(p.y);
						var g:int = src.getGray(x + (px - originX), y + (py - originY));
						if(g > maxG) maxG = g;
					}	
					
					dest.setGray(x, y, maxG);
				}
			}
			return dest;
		} 
				
	}
}